package com.authine.cloudpivot.ext.controller.tianque;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSONObject;
import com.authine.cloudpivot.engine.api.model.runtime.BizObjectModel;
import com.authine.cloudpivot.engine.api.model.runtime.BizObjectQueryModel;
import com.authine.cloudpivot.engine.component.query.api.FilterExpression;
import com.authine.cloudpivot.engine.component.query.api.Page;
import com.authine.cloudpivot.engine.enums.type.QueryDisplayType;
import com.authine.cloudpivot.ext.model.BaseModel;
import com.authine.cloudpivot.ext.model.MinqingminfangModel;
import com.authine.cloudpivot.ext.util.ExtClassUtils;
import com.authine.cloudpivot.web.api.controller.base.BaseController;
import com.authine.cloudpivot.web.api.dubbo.DubboConfigService;
import com.authine.cloudpivot.web.api.view.ResponseResult;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

/**
 * 天阙系统数据推送接口
 *
 * @author shinka
 */
@Api(value = "天阙系统推送数据", tags = "01::EXTAPI::天阙系统推送数据")
@Controller
@RequestMapping("/public/ext/tianque")
public class ExtTianqueController extends BaseController {

    private static Logger log = LoggerFactory.getLogger(ExtTianqueController.class);

    @Value("${file.downloadUrl}")
    private String fileDownloadUrl;

    @Value("${tianque.platform_appKey}")
    private String tq_platform_appKey;

    // @Value("${tianque.departmentNo}")
    // private String tq_departmentNo;

    @Value("${tianque.sourcePlatfromCode}")
    private String tq_sourcePlatfromCode;

    @Value("${tianque.getway_pathCode}")
    private String tq_getway_pathCode;

    @Value("${tianque.getway_appKey}")
    private String tq_getway_appKey;

    @Value("${tianque.url_issueEvaluateAddition}")
    private String tq_url_issueEvaluateAddition;

    @Value("${tianque.url_appeal}")
    private String tq_url_appeal;

    private String adminUserId = "2c9280a26706a73a016706a93ccf002b";

    @Autowired
    private DubboConfigService dubboConfigService;

    /**
     * 预受理新增
     * 
     * @param params
     * @return
     */
    @ApiOperation(value = "预受理新增")
    @PostMapping("/createAppeal")
    @ResponseBody
    public ResponseResult<String> createAppeal(@RequestBody Map<String, Object> params) {
        log.info("createAppeal start params = {}", params);
        try {
            String objectId = String.valueOf(params.get("objectId"));
            String schemaCode = String.valueOf(params.get("schemaCode"));
            String queryCode = String.valueOf(params.get("queryCode"));
            // 根据object查询表数据
            Map<String, Object> formData = queryFormData(objectId, schemaCode, queryCode);
            // String ownerId = String.valueOf(formData.get(BaseModel.owner));
            String vallageId = String.valueOf(formData.get("corpId"));
            // 查询部门编码
            String departmentNo = queryTianqueDepartmentNo(vallageId);
            formData.put("departmentNo", departmentNo);
            // 组装接口参数
            JSONObject apiParams = buildCreateAppealParams(schemaCode, formData);
            log.debug("请求天阙平台入参：{}", apiParams.toJSONString());
            // 调用天阙接口推送数据
            JSONObject apiResult = TianqueApiManage.submitTQData(tq_url_appeal, apiParams, "");
            log.debug("预受理新增，天阙平台接口返回内容：{}", apiResult);
            // 解析返回结果
            JSONObject updateParams = new JSONObject();
            updateParams.put("syncStatus", false);
            if (apiResult.size() > 0) {
                Boolean syncStatus = Boolean.valueOf(apiResult.get("success").toString());
                if (!syncStatus) {
                    throw new Exception("预受理新增失败，天阙接口返回值为：" + apiResult);
                }
                updateParams = (JSONObject)apiResult.get("data");
                updateParams.put("syncStatus", syncStatus);
            }
            // 更新表单数据
            String result = updateFormData(adminUserId, schemaCode, objectId, updateParams);
            return getOkResponseResult(result, "预受理新增完成，apiResult=" + apiResult.toString());
        } catch (Exception e) {
            log.error("预受理新增失败：{}", e);
            return getErrResponseResult(null, null, "预受理新增失败：" + e.toString());
        }
    }

    /**
     * 新增主评价接口
     * 
     * @param params
     * @return
     */
    // @ApiOperation(value = "新增主评价接口")
    // @PostMapping("/issueEvaluateAddition")
    // @ResponseBody
    // public ResponseResult<String> issueEvaluateAddition(@RequestBody Map<String, Object> params) {
    // log.info("issueEvaluateAddition start params = {}", params);
    // try {
    // String objectId = String.valueOf(params.get("objectId"));
    // String schemaCode = String.valueOf(params.get("schemaCode"));
    // String queryCode = String.valueOf(params.get("queryCode"));
    // // 根据object查询表数据
    // Map<String, Object> data = queryFormData(objectId, schemaCode, queryCode);
    // // 组装接口参数
    // JSONObject apiParams = buildIssueEvaluateAdditionParams(schemaCode, data);
    // // 调用天阙接口推送数据
    // JSONObject apiResult = TianqueApiManage.submitTQData(tq_url_issueEvaluateAddition, apiParams, "");
    // log.debug("新增主评价，天阙平台接口返回内容：{}", apiResult);
    // // 解析返回结果
    // String result = null;
    // if (apiResult.size() > 0) {
    // result = apiResult.get("success").toString();
    // }
    // return getOkResponseResult(result, "新增主评价成功");
    // } catch (Exception e) {
    // log.error("新增主评价失败：{}", e);
    // return getErrResponseResult(null, null, "新增主评价失败：" + e.toString());
    // }
    // }

    @SuppressWarnings("unchecked")
    private Map<String, Object> queryFormData(String objectId, String schemaCode, String queryCode) throws Exception {
        log.info("queryFormData start. params={},schemaCode={},queryCode={}", objectId, schemaCode, queryCode);

        if (StringUtils.isEmpty(objectId)) {
            final String exStr = "查询结果异常，objectId为空";
            log.error(exStr);
            throw new Exception(exStr);
        }

        List<String> columns = Lists.newArrayList();
        List<String> list = ExtClassUtils.getFiledsValue(MinqingminfangModel.class);
        list.remove(MinqingminfangModel.MODEL_MQMF);
        for (String s : list) {
            columns.add(s);
        }

        // List<FilterExpression> filterList = Lists.newArrayList();
        // filterList.add(new FilterExpression.Item("id", FilterExpression.Op.Eq, objectId));
        // FilterExpression.And filter = new FilterExpression.And(filterList);
        FilterExpression filter = new FilterExpression.Item(BaseModel.id, FilterExpression.Op.Eq, objectId);

        BizObjectQueryModel.Options options = new BizObjectQueryModel.Options();
        options.setQueryDisplayType(QueryDisplayType.APPEND);
        options.setCustomDisplayColumns(columns);

        BizObjectQueryModel query = new BizObjectQueryModel();
        query.setOptions(options);
        query.setFilterExpr(filter);
        query.setSchemaCode(schemaCode);
        query.setQueryCode(queryCode);

        Page<BizObjectModel> resultPage = dubboConfigService.getBizObjectFacade().queryBizObjects(query);
        List<BizObjectModel> content = Lists.newArrayList();
        if (resultPage != null) {
            content = (List<BizObjectModel>)resultPage.getContent();
        }
        // 正常情况只会查询一条数据出来
        if (content.size() == 0 || content.size() > 1) {
            final String exStr = "查询表单数据，查询结果异常，根据ID查询结果为空或大于1";
            log.error(exStr);
            throw new Exception(exStr);
        }

        log.info("queryFormData end.", "");
        return content.get(0).getData();
    }

    /**
     * 根据组织ID（村编码）查询天阙系统部门编码
     * 
     * @param vallageId
     * @return
     * @throws Exception
     */
    @SuppressWarnings("unchecked")
    private String queryTianqueDepartmentNo(String villageId) throws Exception {
        log.info("queryTianqueDepartmentNo start. villageId={}", villageId);

        final String SCHEMACODE_GJY = "gjy";
        final String DATAITEMS_VALLAGEID = "ShortText1623401417630";
        final String DATAITEMS_TOWNCODE = "ShortText1623401413654";

        if (StringUtils.isEmpty(villageId)) {
            final String exStr = "查询结果异常, 村编码为空";
            log.error(exStr);
            throw new Exception(exStr);
        }

        List<String> columns = Lists.newArrayList();
        columns.add(DATAITEMS_VALLAGEID);
        columns.add(DATAITEMS_TOWNCODE);

        FilterExpression filter = new FilterExpression.Item(DATAITEMS_VALLAGEID, FilterExpression.Op.Eq, villageId);

        BizObjectQueryModel.Options options = new BizObjectQueryModel.Options();
        options.setQueryDisplayType(QueryDisplayType.APPEND);
        options.setCustomDisplayColumns(columns);

        BizObjectQueryModel query = new BizObjectQueryModel();
        query.setOptions(options);
        query.setFilterExpr(filter);
        query.setSchemaCode(SCHEMACODE_GJY);
        query.setQueryCode(SCHEMACODE_GJY);

        Page<BizObjectModel> resultPage = dubboConfigService.getBizObjectFacade().queryBizObjects(query);
        List<BizObjectModel> content = Lists.newArrayList();
        if (resultPage != null) {
            content = (List<BizObjectModel>)resultPage.getContent();
        }
        // 正常情况只会查询一条数据出来
        if (content.size() == 0 || content.size() > 1) {
            final String exStr = "queryTianqueDepartmentNo error，查询结果异常，根据ID查询结果为空或大于1";
            log.error(exStr);
            throw new Exception(exStr);
        }

        Map<String, Object> resultMap = content.get(0).getData();
        String departmentNo = String.valueOf(resultMap.get(DATAITEMS_TOWNCODE));
        if (StringUtils.isEmpty(departmentNo)) {
            log.error("departmentNo is null");
            throw new Exception("departmentNo is null");
        }
        log.info("queryTianqueDepartmentNo end, departmentNo={}", departmentNo);
        return departmentNo;
    }

    private String updateFormData(String userId, String schemaCode, String objectId, JSONObject json) {
        Boolean syncStatus = json.getBoolean("syncStatus");
        Map<String, Object> data = new HashMap<>();
        data.put(BaseModel.id, objectId);
        // if (MinqingminfangModel.MODEL_MQMF.equals(schemaCode) ||
        // JiandouyidiantongModel.MODEL_MQMF.equals(schemaCode)) {
        if (syncStatus) {
            data.put(MinqingminfangModel.syncStatus, 1);
            // data.put(MinqingminfangModel.matterName, json.get("subject"));
            data.put(MinqingminfangModel.matterExplain, json.get("issueContent"));
            data.put(MinqingminfangModel.issueId, json.get("id"));
            data.put(MinqingminfangModel.serialNumber, json.get("serialNumber"));
            data.put(MinqingminfangModel.corpName, json.get("orgId"));
        } else {
            data.put(MinqingminfangModel.syncStatus, 0);
        }
        data.put(MinqingminfangModel.syncDate, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        BizObjectModel model = new BizObjectModel(schemaCode, data, false);
        return dubboConfigService.getBizObjectFacade().saveBizObject(userId, model, true);
        // }
        // return objectId;
    }

    @SuppressWarnings("unchecked")
    private JSONObject buildCreateAppealParams(String schemaCode, Map<String, Object> params) {
        JSONObject json = new JSONObject();
        json.put("appKey", tq_platform_appKey);
        json.put("sourcePlatformCode", tq_sourcePlatfromCode); // 部门编码oid、departmentNo二选一
        // json.put("departmentNo", tq_departmentNo); // 易和组织机构唯一编码departmentNo、oid二选一
        json.put("departmentNo", params.get("departmentNo"));
        // json.put("oid", "");

        String occurDate = String.valueOf(params.get(MinqingminfangModel.Date1620194843440));
        String reportSerialNumber = schemaCode + "-" + params.get("id");
        List<Map<String, Object>> attachFileJsonList =
            (List<Map<String, Object>>)params.get(MinqingminfangModel.Attachment1620195029230);
        List<JSONObject> attachFileList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(attachFileJsonList)) {
            for (Map<String, Object> m : attachFileJsonList) {
                String fileName = m.get("name").toString();
                JSONObject j = new JSONObject();
                String refId = m.get("refId").toString();
                j.put("fileName", fileName);
                j.put("fullUrl", fileDownloadUrl + refId);
                j.put("type", m.get("mimeType"));
                j.put("uri", "");
                attachFileList.add(j);
            }
        }
        json.put("createUser", params.get(MinqingminfangModel.ShortText1620194855262)); // 创建人 非必填
        json.put("dealUserMobile", params.get(MinqingminfangModel.ShortText1620194889728));// 创建人手机 非必填
        json.put("issueContent", params.get(MinqingminfangModel.LongText1620194922653)); // 事件描述 必填
        json.put("occurDate", occurDate); // 事件的发生时间 必填 format: date-time
        json.put("reportSerialNumber", reportSerialNumber); // 第三方事件编号 非必填
        json.put("attachFileList", attachFileList); // 附件列表 非必填
        json.put("occurLocation", params.get(MinqingminfangModel.ShortText1624633059020));// 事发地点 非必填

        json.put("important", params.get("important"));// 是否重大事件 非必填
        json.put("isEmergency", params.get("isEmergency"));// 是否紧急事件 非必填
        json.put("lon", params.get("lon"));// WGS-84坐标系 经度 非必填
        json.put("lat", params.get("lat"));// WGS-84坐标系 纬度 非必填
        json.put("addressCode", params.get("addressCode"));// 地址库编码 非必填
        json.put("subject", params.get(BaseModel.name)); // 事件名称 必填 最大长度: 100 最小长度: 2
        json.put("categoryCode", params.get("categoryCode")); // 分类编码 非必填
        // attachFileList
        // -- fileName string 必须 附件文件名(eg:20210512.png)
        // -- fullUrl string 必须 附件的全路径
        // -- type string 必须 附件类型(mp3,png,xls等)
        // -- uri string 非必须 文件存放半路径
        json.put("issueRelevances", params.get("issueRelevances")); // 事件关联信息集合 非必填
        // issueRelevances
        // -- mobilePhone string 非必须 联系电话 最大长度: 32最小长度: 0
        // -- objName string 必须 名称 最大长度: 64最小长度: 0
        // -- relevanceClassification integer 必须 关联分类，1.人员，2.场所，3.企业，4.设备，5.河道 format:
        // int32
        // -- relevanceClassificationId string 非必须 关联分类id，人员身份证号或企业统一代码

        return json;
    }

    // @SuppressWarnings("unchecked")
    // private JSONObject buildIssueEvaluateAdditionParams(String schemaCode, Map<String, Object> params) {
    // JSONObject json = new JSONObject();
    // json.put("sourcePlatformCode", tq_sourcePlatfromCode);// 来源平台编码
    // if (MinqingminfangModel.MODEL_MQMF.equals(schemaCode)) {
    // // 获取评价子表
    // List<Map<String, Object>> childList =
    // (List<Map<String, Object>>)params.get(MinqingminfangModel.Sheet1622181938529);
    // if (!CollectionUtils.isEmpty(childList)) {
    // for (Map<String, Object> m : childList) {
    // json.put("globalEvaluate", m.get("globalEvaluate"));// 评价打分，分值1-5 必填
    // json.put("content", m.get("content"));// 评价内容，最多800字 必填
    // json.put("evaluateUser", m.get("evaluateUser"));// 评价人 必填
    // json.put("evaluateUserMobile", m.get("evaluateUserMobile"));// 评价人联系方式 必填
    // }
    // }
    // json.put("issueId", params.get(MinqingminfangModel.issueId)); // 事件id 必填
    // json.put("serialNumber", params.get(MinqingminfangModel.serialNumber));// 事件单号 必填
    // json.put("issueContent", params.get(MinqingminfangModel.LongText1620194922653)); // 事件描述 非必填
    // } else if (JiandouyidiantongModel.MODEL_JDYDT.equals(schemaCode)) {
    // // 获取评价子表
    // json.put("globalEvaluate", params.get(JiandouyidiantongModel.ShortText1622274157905));// 评价打分，分值1-5 必填
    // json.put("content", params.get(JiandouyidiantongModel.ShortText1622274157905));// 评价内容，最多800字 必填
    // json.put("evaluateUser", params.get(JiandouyidiantongModel.ShortText1622273488527));// 评价人 必填
    // json.put("evaluateUserMobile", params.get(JiandouyidiantongModel.ShortText1622273573734));// 评价人联系方式 必填
    // json.put("issueId", params.get("issueId")); // 事件id 必填
    // json.put("serialNumber", params.get("serialNumber"));// 事件单号 必填
    // json.put("issueContent", params.get(JiandouyidiantongModel.LongText1622274098955)); // 事件描述 非必填
    // }
    //
    // return json;
    // }

}
